package org.fastsyncer.worker.framework;

import java.util.concurrent.ConcurrentLinkedQueue;

import org.fastsyncer.common.entity.MappingTask;
import org.fastsyncer.parser.framework.ParserFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WorkerFactory {

	private static Logger logger = LoggerFactory.getLogger(WorkerFactory.class);

	private static WorkerFactory instance = new WorkerFactory();

	private WorkerFactory() {
	}

	public static WorkerFactory getInstance() {
		return instance;
	}

	/**
	 * 全量同步
	 * @param mappingTask
	 * @param distributeTask
	 * @return
	 */
	public JSONObject handle(MappingTask mappingTask, ConcurrentLinkedQueue<Integer[]> distributeTask) {
		try {
			logger.info("执行同步任务:" + mappingTask.getName());
			// 执行批量同步任务
			return new WorkerThreadPool().sync(mappingTask, distributeTask);
		} catch (Exception e) {
			logger.error("执行批量同步任务时异常：" + e.getMessage(), e.getCause());
		}
		return null;
	}

	/**
	 * 增量同步
	 * @param mappingTask
	 * @param msg
	 * @return
	 * @throws Exception
	 */
	public JSONObject handle(MappingTask mappingTask, JSONObject msg) throws Exception {
		// 同步结果
		JSONObject result = null;
		JSONArray arr = msg.getJSONArray("msg");
		int msgLen = arr.length();
		for (int i = 0; i < msgLen; i++) {
			JSONObject row = (JSONObject) arr.get(i);
			String eventType = row.getString("eventType");
			JSONArray before = row.getJSONArray("before");
			JSONArray after = row.getJSONArray("after");

			try {
				//执行增量操作，如果失败会抛出异常，否则返回true
				ParserFactory.getInstance().parse(mappingTask, eventType, before, after);
			} catch (Exception e) {
				if (result == null) {
					result = new JSONObject();
					result.put("name", mappingTask.getName());
					result.put("error", 0);
					result.put("reason", new JSONArray());
				}

				try {
					// 不用考虑高并发场景，直接累加
					int error = result.getInt("error") + 1;
					result.put("error", error);

					// 记录错误信息
					JSONArray reason = result.getJSONArray("reason");
					JSONObject err = new JSONObject();
					err.put("params", after);
					err.put("cause", e.getCause());
					err.put("message", e.getMessage());
					reason.put(reason.length(), err);
					result.put("reason", reason);
				} catch (JSONException e1) {
					logger.error("记录错误信息时：转换JSONObject异常！");
				}
			}
		}
		return result;
	}

}
